import { ConfigSvr } from './../../services/config';
import { CanAllBeFinish } from './pipe';
import { MessageBoxService, GrowlMessageType, notOperateOnLoading } from './../../components/messageBox';
import { AppStore } from './../../services/appStore';
import { KdsMessageType, FNCManager } from './../../utils/fnc/fncManager';
import { Order, Orderitem } from './../../models/order';
import { OrderBy } from './../../utils/pipes/date';
import { OrderSvr, OrderPriority } from './../../services/order';
import { Component, Input, Inject, ElementRef, ChangeDetectorRef, trigger, animate, transition, style, state } from '@angular/core';
import * as delay from 'delay';

// import {KitchenOrder} from '../models/order';

@Component({
    selector: 'order-panel',
    template: `
     <section class="panel-container">
        <header [class]="calcPriorityByElapsedTime(10000|delayTimer|async|elapsedTime:order.receiveTime|msecToS)">
            <span class='terminal-name'>{{order.customerIdentity}}</span>
            <span class="flex"></span>
            <span class="new">
                <span class="info">新</span>
            </span>
            <i class="iconfont icon-alarm"></i>
            <span class='elasped-time'>{{10000|delayTimer|async|elapsedTime:order.receiveTime|date:"mm:ss"}}</span>
        </header>
        <article [id]="'order-'+order.id">
            <div class='cart-item' *ngFor="let item of order.items;let i=index;trackBy:trackById" [@heroState]="item.animationState" [class.no-localstall]='!item.isLocalStall'  (click)="toggleItemCompleted(item.id,item)" [hidden]="!isExpand && !item.isLocalStall" [class.completed]='item.finishTime>0' [class.refund]='item.qty == item.refundQty' [class.first-completed]='(i==0 || !order.items[i-1].finishTime)&&order.items[i].finishTime&&(i==order.items.length-1 || order.items[i+1].finishTime)'>
                <div class="item-info layout-row layout-center" >
                    <div class="container layout-row layout-center flex">
                        <span class='item-qty' [class.multiple]='calcRealQty(item)>1'>{{calcRealQty(item)}}</span>
                        <div class='invt-name '>
                            <span>{{item.inventoryName}}</span>
                        </div>
                    </div>
                    <i class="iconfont  icon-done-circle done"></i>
                </div>
                <div class="modifier"  *ngIf="item.description || (item.modifiers&&item.modifiers&&item.modifiers.length)">
                    <span *ngFor="let option of flatOptions(item.modifiers)" class='modifier-option'>{{option.name}}</span>
                    <span class='modifier-option' *ngIf="item.description">{{item.description}}</span>
                </div>
            </div>
        </article>
        <footer>
            <div class="remark" *ngIf="order.description"><span class='order-remark'>{{order.description}}</span></div>
             <div class="btn layout-row"   [ngClass]="{'produce': order.canFinish}">
                <button (click)="toggleExpand()" class="border-r expand  w layout-row layout-align-center-center">
                    <i class="iconfont  icon-assignment" [class.active]='isExpand'></i>
                </button>
                <button class="dn  up w border-r direction" (click)="up()"><i class="iconfont icon-expand-less"></i></button>
                <button class="dn  down w border-r direction" (click)="down()"><i class="iconfont icon-expand-more"></i></button>
                <button class="flex text" id="complete-order-button" (click)="completeOrder()">
                    {{refund?"关闭":(order.canAllFinish?"整单出品":"出品")}}
                </button>
            </div>
        </footer>
     </section>
    `,
    styleUrls: ['./home.component.scss'],
    animations: [
        trigger('heroState', [
            state('active', style({ transform: ' translateX(100%)', margin: 0 })),
            state('init', style({ transform: ' translateX(0%)' })),
            state('inactive', style({ transform: 'translateX(-100%)', margin: 0 })),
            // transition('* => active', animate('100ms 2000  ease-in')),
            // transition('* => inactive', animate('100ms 2000 ease-out',
            //     style({ transform: 'scale(1) translateX(0%)' })
            // )),
            // transition('* => init', animate('2s 2000  ease-out')),
            // transition('active => void', [
            //     animate('0.1s  ease-out')
            // ]),
            transition('init => active', [
                animate('0.1s  ease-out')
            ]),
            // transition('init => inactive', [
            //     animate('0.1s  ease-out')
            // ]),
            transition('inactive => init', [
                animate('0.1s  ease-out')
            ])
        ])
    ],
    providers: []
})

// trigger('heroState', [
//     state('inactive', style({ transform: 'translateX(0) scale(1)' })),
//     state('active', style({ transform: 'translateX(0) scale(1.1)' })),
//     transition('inactive => active', animate('100ms ease-in')),
//     transition('active => inactive', animate('100ms ease-out')),
//     transition('void => inactive', [
//         style({ transform: 'translateX(-100%) scale(1)' }),
//         animate(100)
//     ]),
//     transition('inactive => void', [
//         animate(100, style({ transform: 'translateX(100%) scale(1)' }))
//     ]),
//     transition('void => active', [
//         style({ transform: 'translateX(0) scale(0)' }),
//         animate(200)
//     ]),
//     transition('active => void', [
//         animate(200, style({ transform: 'translateX(0) scale(0)' }))
//     ])

export class OrderPanel {
    constructor(private element: ElementRef, private appStore: AppStore, private changeDetectorRef: ChangeDetectorRef, private configSvr: ConfigSvr) {
    }
    private _order: Order;
    private isExpand: Boolean = false;
    private cirticalIndex: number;
    private canFinish: Boolean = false;
    private canAllFinish: Boolean = false;
    private refund: Boolean = false;
    @Input()
    set order(order: Order) {
        this._order = order;
        this.refund = this._order.items.filter(x => x.isLocalStall).every(x => x.qty == x.refundQty); //debug
        this.appStore.orderStore.actions.sortItems(order);
        this._order.canFinish = this.canBeFinished();
        this._order.canAllFinish = this.canAllBeFinished();

        // [class.first-completed]='(i==0 || !order.items[i-1].finishTime)&&order.items[i].finishTime&&(i==order.items.length-1 || order.items[i+1].finishTime)'
    }
    get order() {
        return this._order;
    }
    private trackById(index, orderItem) {
        return orderItem.id;
    }
    private canAllBeFinished() {
        return this.order.items && this.order.items.filter(x => x.qty != x.refundQty).every(x => Boolean(x.finishTime));
    }
    private isScorllHeight(ele) {
        return ele.scrollHeight > ele.clientHeight;
    }
    private calcRealQty(item) {
        const qty = (item.qty > item.refundQty) ? item.qty - item.refundQty : item.qty;
        return qty;
    }
    private flatOptions(modifiers) {
        if (modifiers.length == 0) return [];
        return modifiers.map(x => x.options).reduce((x, y) => x.concat(y))
    }
    private toggleExpand() {
        this.isExpand = !this.isExpand;
        const section = this.element.nativeElement.firstElementChild;
        const ele = section.children[1];
        setTimeout(function () {
            if (this.isScorllHeight(ele)) {
                section.classList.add("scorll");
            } else {
                section.classList.remove("scorll");
            }
        }.bind(this), 1);
    }
    private calcPriorityByElapsedTime(elapsedTime: number) {
        const addClass = " layout-row layout-align-center-center";
        const periority = this.appStore.orderStore.actions.calcPriorityByElapsedTime(elapsedTime);
        if (periority == OrderPriority.normal) {
            return "priority-normal" + addClass;
        } else if (periority == OrderPriority.high) {
            return "priority-high" + addClass;
        } else {
            return "priority-extreme-high" + addClass;
        }
    }
    private canBeFinished() {
        return this.order.items && this.order.items.filter(x => x.qty != x.refundQty).every(x => !x.isLocalStall || Boolean(x.finishTime))
    }

    @notOperateOnLoading()
    private async completeOrder() {
        try {
            if (this.refund) {
                await this.appStore.orderStore.actions.closeOrder(this.order.id);
            } else if (this.order.items.filter(x => x.isLocalStall && !x.deliverTime).filter(x => x.qty != x.refundQty).some(x => !x.finishTime)) {
                await this.appStore.orderStore.actions.completeBranchOrderItems(this.order.id);
            } else {
                await this.appStore.orderStore.actions.completeOrder(this.order.id);
            }
        } catch (error) {
            MessageBoxService.current.Growl(GrowlMessageType.Error, "错误提示", error.message || error);
        }
    }

    @notOperateOnLoading()
    private async toggleItemCompleted(itemId: string, item?: Orderitem) {
        try {
            if (!item.isLocalStall) {
                return MessageBoxService.current.Growl(GrowlMessageType.Error, "操作错误", "这道菜品正在其他档口制作");
            }
            await this.appStore.orderStore.actions.toggleCartItemFinish(this.order.id, itemId);

            //todo 在这里计算 ?
            this._order.canFinish = this.canBeFinished();
            this._order.canAllFinish = this.canAllBeFinished();

            this.changeDetectorRef.detectChanges();

            var order = this._order;
            //先等待一秒
            //更换动画效果
            const sortedOrder = JSON.parse(JSON.stringify(order));
            this.appStore.orderStore.actions.sortItems(sortedOrder);
            if (order.items.findIndex(x => x.id == itemId) == sortedOrder.items.findIndex(x => x.id == itemId)) {
                this.appStore.orderStore.actions.sortItems(order);
                return;
            }
            order.items.find(x => x.id == itemId).animationState = "init";
            this.changeDetectorRef.detectChanges();
            //需要等待两秒排序，notify数据
            await delay(10);
            order.items.find(x => x.id == itemId).animationState = "active";
            this.changeDetectorRef.detectChanges();
            await delay(210);
            this.appStore.orderStore.actions.sortItems(order);
            // order.items.find(x => x.id == itemId).animationState = "inactive";
            // this.changeDetectorRef.detectChanges();
            // await delay(10);
            order.items.find(x => x.id == itemId).animationState = "init";
            this.changeDetectorRef.detectChanges();

        } catch (error) {
            MessageBoxService.current.Growl(GrowlMessageType.Error, "错误提示", error.message || error);
        }
    }
    private up() {
        const article = this.element.nativeElement.firstElementChild.children[1];
        article.scrollTop -= article.clientHeight;
    }
    private down() {
        const article = this.element.nativeElement.firstElementChild.children[1];
        article.scrollTop += article.clientHeight;
    }
    private ngAfterViewInit() {
        this.resetPanelState(this.configSvr.orderConfig.count);
    }
    private resetPanelState(count: number) {
        const self = this;
        const section = this.element.nativeElement.firstElementChild;
        const ele = section.children[1];
        for (let i = 1; i <= count; i++) {
            this.element.nativeElement.style.height = ((i / count) * 100).toFixed(4).toString() + "%";;
            if (!this.isScorllHeight(ele) || i == count) {
                break;
            }
        }

        this.element.nativeElement.style.opacity = "100";
        if (this.isScorllHeight(ele)) {
            section.classList.add("scorll");
        }
    }
    private ngOnInit() {
    }
}
